package com.xiashitech.apiservice.service.impl;

import com.xiashitech.apiservice.dao.AgentSystemStatusMapper;
import com.xiashitech.apiservice.dao.model.AgentSystemStatus;
import com.xiashitech.apiservice.service.IAgentSystemStatusService;
import com.xiashitech.interfaces.agent.constants.AgentStatus;
import com.xiashitech.interfaces.agent.dto.SystemInfoDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("agentSystemStatusService")
@RequiredArgsConstructor(onConstructor =@_(@Autowired))
public class AgentSystemStatusServiceImpl implements IAgentSystemStatusService {

    private final AgentSystemStatusMapper agentSystemStatusMapper;

    @Override
    public List<SystemInfoDTO> selectAgentStatus(SystemInfoDTO systemInfoDTO) {
        List<AgentSystemStatus> agentSystemStatusList = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemInfoDTO.getId()).microServiceId(systemInfoDTO.getMicroServiceId()).agentStatus(systemInfoDTO.getAgentStatus()).searchStartDate(systemInfoDTO.getSearchStartDate()).searchEndDate(systemInfoDTO.getSearchEndDate()).build());
        if(agentSystemStatusList.size() == 0) {
            return Collections.emptyList();
        }
        return agentSystemStatusList.stream().map(agentSystemStatus -> SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).host(agentSystemStatus.getHost()).microServiceId(agentSystemStatus.getMicroServiceId()).host(agentSystemStatus.getHost()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build()).collect(Collectors.toList());
    }

    @Cacheable(value="agentStatus", key="#systemId+'-'+#microServiceId", sync = true)
    @Override
    public SystemInfoDTO selectAgentStatusByCache(String systemId, String microServiceId) {
        if(systemId == null || "".equals(systemId) || microServiceId == null || "".equals(microServiceId)) {
            return null;
        }
        List<AgentSystemStatus> agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).build());
        if(agentSystemStatuses.size() == 0) {
            return null;
        }
        AgentSystemStatus agentSystemStatus = agentSystemStatuses.get(0);
        return SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).host(agentSystemStatus.getHost()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build();
    }

    @CachePut(cacheNames="agentStatus", key="#systemInfoDTO.id+'-'+#systemInfoDTO.microServiceId", unless="#result == null")
    @Override
    public SystemInfoDTO insertAgentStatus(SystemInfoDTO systemInfoDTO) {
        AgentSystemStatus agentSystemStatus = AgentSystemStatus.builder().systemId(systemInfoDTO.getId()).microServiceId(systemInfoDTO.getMicroServiceId()).agentStatus(systemInfoDTO.getAgentStatus()).createTime(new Date()).heartBeat(new Date()).build();
        agentSystemStatusMapper.insertAgentStatus(agentSystemStatus);
        List<AgentSystemStatus> agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).build());
        agentSystemStatus = agentSystemStatuses.get(0);
        return SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build();
    }

    @Override
    public void updateAgentStatus(SystemInfoDTO systemInfoDTO) {
        agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemInfoDTO.getId()).microServiceId(systemInfoDTO.getMicroServiceId()).agentStatus(systemInfoDTO.getAgentStatus()).updateTime(new Date()).heartBeat(new Date()).build());
    }

    @CachePut(cacheNames="agentStatus", key="#systemId+'-'+#microServiceId", unless="#result == null")
    @Override
    public SystemInfoDTO updateAgentStatusByCache(String systemId, String microServiceId, Integer agentStatus, Boolean heartBeat) {
        if(systemId == null || "".equals(systemId) || microServiceId == null || "".equals(microServiceId)) {
            return null;
        }
        if(heartBeat) {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).agentStatus(agentStatus).updateTime(new Date()).heartBeat(new Date()).build());
        } else {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).agentStatus(agentStatus).updateTime(new Date()).build());
        }
        List<AgentSystemStatus> agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).build());
        AgentSystemStatus agentSystemStatus = agentSystemStatuses.get(0);
        return SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build();
    }
    @CachePut(cacheNames = "agentStatus", key = "#systemId+'-'+#microServiceId", unless = "#result == null")
    @Override
    public SystemInfoDTO updateAgentHostByCache(String systemId, String microServiceId, String host, Boolean heartBeat) {
        if (systemId == null || "".equals(systemId) || microServiceId == null || "".equals(microServiceId)) {
            return null;
        }
        if (heartBeat) {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).host(host).updateTime(new Date()).heartBeat(new Date()).build());
        } else {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).host(host).updateTime(new Date()).build());
        }
        List<AgentSystemStatus> agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemId).host(host).microServiceId(microServiceId).build());
        AgentSystemStatus agentSystemStatus = agentSystemStatuses.get(0);
        return SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).host(agentSystemStatus.getHost()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build();
    }

    @CachePut(cacheNames="agentStatus", key="#systemId+'-'+#microServiceId", unless="#result == null")
    @Override
    public SystemInfoDTO updateAgentHeartBeatByCache(String systemId, String microServiceId) {
        if(systemId == null || "".equals(systemId) || microServiceId == null || "".equals(microServiceId)) {
            return null;
        }
        List<AgentSystemStatus> agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).build());
        if(agentSystemStatuses.size() == 0) {
            return null;
        }
        AgentSystemStatus agentSystemStatus = agentSystemStatuses.get(0);
        if(agentSystemStatus.getAgentStatus() == AgentStatus.NOT_RUN.getValue()) {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).agentStatus(AgentStatus.RUNNING.getValue()).heartBeat(new Date()).build());
        } else {
            agentSystemStatusMapper.updateAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).heartBeat(new Date()).build());
        }
        agentSystemStatuses = agentSystemStatusMapper.selectAgentStatus(AgentSystemStatus.builder().systemId(systemId).microServiceId(microServiceId).build());
        agentSystemStatus = agentSystemStatuses.get(0);
        return SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).agentStatus(agentSystemStatus.getAgentStatus()).agentStatusCreate(agentSystemStatus.getCreateTime()).agentStatusUpdate(agentSystemStatus.getUpdateTime()).agentStatusHeartBeat(agentSystemStatus.getHeartBeat()).build();
    }

    public List<SystemInfoDTO> selectAllAgentStatus() {
        return agentSystemStatusMapper.selectAllAgentStatus().stream().map(agentSystemStatus -> SystemInfoDTO.builder().id(agentSystemStatus.getSystemId()).microServiceId(agentSystemStatus.getMicroServiceId()).build()).collect(Collectors.toList());
    }
}
